<?php

/**
 * This file is part of easyCMS.
 *
 * (c) 2023 easyCMS <easyCMS@easycms.net.cn>
 *
 * For the full copyright and license information, please view
 * the LICENSE file that was distributed with this source code.
 */

namespace app\command;

use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Webman\Console\Util;

class MakeValidate extends Command
{
    protected static $defaultName        = 'make:validate';
    protected static $defaultDescription = 'Make validate';

    /**
     * @return void
     */
    protected function configure()
    {
        $this->addArgument('name', InputArgument::OPTIONAL, 'Make validate');
    }

    protected function execute(InputInterface $input, OutputInterface $output): int
    {
        $name = $input->getArgument('name');
        $output->writeln("Make validate {$name}");
        $name .= 'Validate';
        $name = str_replace('\\', '/', $name);
        if (! ($pos = strrpos($name, '/'))) {
            $name         = ucfirst($name);
            $validate_str = Util::guessPath(app_path(), 'validate') ?: 'validate';
            $file         = app_path() . "/{$validate_str}/{$name}.php";
            $namespace    = $validate_str === 'Validate' ? 'App\Validate' : 'app\validate';
        } else {
            $name_str = substr($name, 0, $pos);
            if ($real_name_str = Util::guessPath(app_path(), $name_str)) {
                $name_str = $real_name_str;
            } elseif ($real_section_name = Util::guessPath(app_path(), strstr($name_str, '/', true))) {
                $upper = strtolower($real_section_name[0]) !== $real_section_name[0];
            } elseif ($real_base_validate = Util::guessPath(app_path(), 'validate')) {
                $upper = strtolower($real_base_validate[0]) !== $real_base_validate[0];
            }
            $upper ??= strtolower($name_str[0]) !== $name_str[0];
            if ($upper && ! $real_name_str) {
                $name_str = preg_replace_callback('/\/([a-z])/', static fn ($matches) => '/' . strtoupper($matches[1]), ucfirst($name_str));
            }
            $path      = "{$name_str}/" . ($upper ? 'Validate' : 'validate');
            $name      = ucfirst(substr($name, $pos + 1));
            $file      = app_path() . "/{$path}/{$name}.php";
            $namespace = str_replace('/', '\\', ($upper ? 'App/' : 'app/') . $path);
        }
        $this->createValidate($name, $namespace, $file);

        return self::SUCCESS;
    }

    protected function createValidate($name, $namespace, $file): void
    {
        $path = pathinfo($file, PATHINFO_DIRNAME);
        if (! is_dir($path)) {
            mkdir($path, 0777, true);
        }
        $validate_content = <<<EOF
            <?php

            namespace {$namespace};

            use think\\Validate;

            class {$name} extends Validate
            {
                protected \$rule =   [
                    'name'  => 'require|max:25',
                    'age'   => 'number|between:1,120',
                    'email' => 'email',
                ];

                protected \$message  =   [
                    'name.require' => '名称必须',
                    'name.max'     => '名称最多不能超过25个字符',
                    'age.number'   => '年龄必须是数字',
                    'age.between'  => '年龄只能在1-120之间',
                    'email'        => '邮箱格式错误',
                ];

                protected \$scene = [
                    'edit'  =>  ['name','age'],
                ];
            }

            EOF;
        file_put_contents($file, $validate_content);
    }
}
